import { KaTeXRenderer } from '../renderer/KaTeXRenderer';
import type { ExportFormat, ExportOptions } from '../../types';

/**
 * 公式导出器 - 负责将公式导出为不同格式
 */
export class FormulaExporter {
  /**
   * 导出公式
   * @param latex LaTeX代码
   * @param options 导出选项
   * @returns 导出结果
   */
  static export(latex: string, options: ExportOptions): Promise<{ success: boolean; data?: string | Blob; error?: string }> {
    switch (options.format) {
      case 'latex':
        return Promise.resolve(this.exportAsLatex(latex));
      case 'mathml':
        return Promise.resolve(this.exportAsMathML(latex));
      case 'svg':
        return Promise.resolve(this.exportAsSvg(latex));
      case 'png':
        return this.exportAsPng(latex, options.pngResolution || 300);
      default:
        return Promise.resolve({
          success: false,
          error: `不支持的导出格式: ${options.format}`
        });
    }
  }

  /**
   * 导出为LaTeX代码
   */
  private static exportAsLatex(latex: string): { success: boolean; data?: string; error?: string } {
    try {
      return {
        success: true,
        data: latex
      };
    } catch (error) {
      return {
        success: false,
        error: '导出LaTeX失败'
      };
    }
  }

  /**
   * 导出为MathML
   */
  private static exportAsMathML(latex: string): { success: boolean; data?: string; error?: string } {
    try {
      const result = KaTeXRenderer.renderToMathML(latex);
      if (result.error) {
        return {
          success: false,
          error: result.error
        };
      }
      return {
        success: true,
        data: result.mathml
      };
    } catch (error) {
      return {
        success: false,
        error: '导出MathML失败'
      };
    }
  }

  /**
   * 导出为SVG
   */
  private static exportAsSvg(latex: string): { success: boolean; data?: string; error?: string } {
    try {
      const result = KaTeXRenderer.renderToSvg(latex);
      if (result.error) {
        return {
          success: false,
          error: result.error
        };
      }
      return {
        success: true,
        data: result.svg
      };
    } catch (error) {
      return {
        success: false,
        error: '导出SVG失败'
      };
    }
  }

  /**
   * 导出为PNG
   */
  private static exportAsPng(latex: string, resolution: number): Promise<{ success: boolean; data?: Blob; error?: string }> {
    return new Promise((resolve) => {
      try {
        // 渲染为SVG
        const svgResult = KaTeXRenderer.renderToSvg(latex);
        if (svgResult.error) {
          resolve({
            success: false,
            error: svgResult.error
          });
          return;
        }

        // 创建DOM元素
        const svgElement = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
        const svgDoc = new DOMParser().parseFromString(svgResult.svg, 'image/svg+xml');
        const katexSvg = svgDoc.querySelector('svg');
        
        if (!katexSvg) {
          resolve({
            success: false,
            error: '无法解析SVG'
          });
          return;
        }

        // 设置SVG属性
        svgElement.innerHTML = katexSvg.innerHTML;
        svgElement.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
        svgElement.setAttribute('width', katexSvg.getAttribute('width') || '300');
        svgElement.setAttribute('height', katexSvg.getAttribute('height') || '100');

        // 设置背景为白色
        const rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
        rect.setAttribute('width', '100%');
        rect.setAttribute('height', '100%');
        rect.setAttribute('fill', 'white');
        svgElement.insertBefore(rect, svgElement.firstChild);

        // 转换为base64
        const svgData = new XMLSerializer().serializeToString(svgElement);
        const canvas = document.createElement('canvas');
        const ctx = canvas.getContext('2d');
        
        if (!ctx) {
          resolve({
            success: false,
            error: '无法创建Canvas'
          });
          return;
        }

        // 设置Canvas尺寸（根据分辨率）
        const scale = resolution / 96; // 96dpi 是标准屏幕分辨率
        const width = parseInt(svgElement.getAttribute('width') || '300', 10);
        const height = parseInt(svgElement.getAttribute('height') || '100', 10);
        
        canvas.width = width * scale;
        canvas.height = height * scale;
        ctx.scale(scale, scale);

        // 创建图像对象
        const img = new Image();
        img.onload = () => {
          // 绘制图像
          ctx.fillStyle = 'white';
          ctx.fillRect(0, 0, width, height);
          ctx.drawImage(img, 0, 0);
          
          // 转换为PNG Blob
          canvas.toBlob((blob) => {
            if (blob) {
              resolve({
                success: true,
                data: blob
              });
            } else {
              resolve({
                success: false,
                error: '无法创建PNG图像'
              });
            }
          }, 'image/png');
        };
        
        img.onerror = () => {
          resolve({
            success: false,
            error: '图像加载失败'
          });
        };
        
        img.src = `data:image/svg+xml;base64,${btoa(unescape(encodeURIComponent(svgData)))}`;
      } catch (error) {
        resolve({
          success: false,
          error: '导出PNG失败'
        });
      }
    });
  }

  /**
   * 下载导出的文件
   * @param data 导出数据
   * @param format 导出格式
   * @param filename 文件名（不含扩展名）
   */
  static download(data: string | Blob, format: ExportFormat, filename: string = 'formula'): void {
    const extension = format;
    const fullFilename = `${filename}.${extension}`;
    
    try {
      if (typeof data === 'string') {
        // 文本类型（LaTeX, MathML, SVG）
        const blob = new Blob([data], { type: this.getMimeType(format) });
        this.downloadBlob(blob, fullFilename);
      } else {
        // Blob类型（PNG）
        this.downloadBlob(data, fullFilename);
      }
    } catch (error) {
      console.error('下载文件失败:', error);
      alert('下载文件失败，请重试');
    }
  }

  /**
   * 下载Blob文件
   */
  private static downloadBlob(blob: Blob, filename: string): void {
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = filename;
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
    URL.revokeObjectURL(url);
  }

  /**
   * 获取MIME类型
   */
  private static getMimeType(format: ExportFormat): string {
    const mimeTypes: Record<ExportFormat, string> = {
      latex: 'text/plain',
      mathml: 'application/mathml+xml',
      svg: 'image/svg+xml',
      png: 'image/png'
    };
    return mimeTypes[format] || 'application/octet-stream';
  }
}